package com.dtkavin.threads.syn;

import java.util.Random;
import java.util.concurrent.*;

/**
 * 同步
 * Created by john on 10/4/16.
 * 类似于cpu的时钟，
 * 用来同步多个线程。达到指定数量后，线程再开始一起执行
 * 用来调整多线程相互配合的节奏
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        final ShareData shareData = new ShareData();
        for (int i = 0; i < 3; i++) {
            executorService.execute(new Runnable() {
                public void run() {
                    shareData.run();
                }
            });
        }

        executorService.shutdown();
    }

    static class ShareData {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);//3个线程，达到这个值后，这3个线程再一起执行接下来的动作

        /**
         * ！！！--此处不能在方法上加synchronied，否则死锁
         */
        public /*synchronized*/ void run() {
            try {
                Thread.sleep(new Random().nextInt(3000));
                System.out.println("run: " + Thread.currentThread().getName() + " finish- 1");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }

            try {
                Thread.sleep(new Random().nextInt(3000));
                System.out.println("run: " + Thread.currentThread().getName() + " finish- 2");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }

            try {
                Thread.sleep(new Random().nextInt(3000));
                System.out.println("run: " + Thread.currentThread().getName() + " finish- 3s");
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}
